package com.lily.aidouzixun.threadpool;

import android.os.AsyncTask;
import android.os.Build;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池
 */
public class GrandCentralPool {

    /**
     *  Trigger for Debug
     */
    static boolean DEBUG = false;


    /**
     * Can't be instance, be singleton
     */
    private GrandCentralPool() {
    }


    private static PoolExecutors dataInstance;
    private static PoolExecutors downloadImgInstance;
    private static PoolExecutors localImgInstance;
    private static PoolExecutors downloadSoftwarenstance;
    private static PoolExecutors otherInstance;
    private static PoolExecutors longlifeInstance;


    /**
     * 初始化线程池
     */
    public static void initAll(int nthread) {
        dataInstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
        downloadImgInstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
        localImgInstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
        downloadSoftwarenstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
        otherInstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
        longlifeInstance = PoolExecutors.newLimitRejectedThreadPool(nthread);
    }


    /**
     * can be changed to public
     */
    private static ExecutorService DATA_TASK_EXECUTOR;
    private static ExecutorService LONGTIME_LIFE_TASK_EXECUTOR;
    private static ExecutorService DOWNLOAD_IMG_TASK_EXECUTOR;
    private static ExecutorService LOCAL_IMG_TASK_EXECUTOR;
    private static ExecutorService DOWNLOAD_SOFTWARE_TASK_EXECUTOR;
    private static ExecutorService OTHER_TASK_EXECUTOR;
    private static ExecutorService SERIAL_TASK_EXECUTOR;


    public static void init(int nthread) {
        initAll(nthread);
        DATA_TASK_EXECUTOR = (ExecutorService) dataInstance;
        LONGTIME_LIFE_TASK_EXECUTOR = (ExecutorService) longlifeInstance;
        DOWNLOAD_IMG_TASK_EXECUTOR = (ExecutorService) downloadImgInstance;
        LOCAL_IMG_TASK_EXECUTOR = (ExecutorService) localImgInstance;
        DOWNLOAD_SOFTWARE_TASK_EXECUTOR = (ExecutorService) downloadSoftwarenstance;
        OTHER_TASK_EXECUTOR = (ExecutorService) otherInstance;
        SERIAL_TASK_EXECUTOR = (ExecutorService) Executors.newSingleThreadExecutor();
    }

    /**
     * 执行异步任务
     */
    public static void executeAsyncTask(AsyncTask task, Executor exec, Object obj) {
        if (exec != null) {
            if (((PoolExecutors) exec).canAddWorkFromLifeGuard()) {
                ((PoolExecutors) exec).addWorkFromLifeGuard();
            }
            if (Build.VERSION.SDK_INT >= 11) {
                task.executeOnExecutor(exec, obj);
            } else {
                task.execute(obj);
            }
        }
    }


    public static void executeAsyncTask(AsyncTask task, Executor exec) {
        if (exec != null) {
            if (((PoolExecutors) exec).canAddWorkFromLifeGuard()) {
                ((PoolExecutors) exec).addWorkFromLifeGuard();
            }
            if (Build.VERSION.SDK_INT >= 11) {
                task.executeOnExecutor(exec);
            } else {
                task.execute();
            }
        }
    }

    /**
     * execute on DataTaskExecutor
     */
    public static void executeDataAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, dataInstance, obj);
    }

    public static void executeDataAsyncTask(AsyncTask task) {
        executeAsyncTask(task, dataInstance);
    }


    /**
     * execute on DownloadImgTaskExecutor
     */
    public static void executeDownloadImgAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, downloadImgInstance, obj);
    }

    public static void executeDownloadImgAsyncTask(AsyncTask task) {
        executeAsyncTask(task, downloadImgInstance);
    }


    /**
     * execute on LocalImgTaskExecutor
     */
    public static void executeLocalImgAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, localImgInstance, obj);
    }

    public static void executeLocalImgAsyncTask(AsyncTask task) {
        executeAsyncTask(task, localImgInstance);
    }


    /**
     * execute on DownloadSoftwareExecutor
     */
    public static void executeDownloadSoftwareAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, downloadSoftwarenstance, obj);
    }

    public static void executeDownloadSoftwareAsyncTask(AsyncTask task) {
        executeAsyncTask(task, downloadSoftwarenstance);
    }


    /**
     * execute on OtherExecutor
     */
    public static void executeOtherAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, otherInstance, obj);
    }

    public static void executeOtherAsyncTask(AsyncTask task) {
        executeAsyncTask(task, otherInstance);
    }

    /**
     * execute on LongTimeLifeExecutor
     */
    public static void executeLongTimeLifeAsyncTask(AsyncTask task, Object obj) {
        executeAsyncTask(task, longlifeInstance, obj);
    }

    public static void executeLongTimeLifeAsyncTask(AsyncTask task) {
        executeAsyncTask(task, longlifeInstance);
    }


    /**
     * execute on SerialExecutor
     */
    public static void executeSerialAsyncTask(AsyncTask task, Object obj) {
        if (Build.VERSION.SDK_INT >= 11 && SERIAL_TASK_EXECUTOR != null) {
            task.executeOnExecutor(SERIAL_TASK_EXECUTOR, obj);
        } else {
            task.execute(obj);
        }
    }

    public static void executeSerialAsyncTask(AsyncTask task) {
        if (Build.VERSION.SDK_INT >= 11 && SERIAL_TASK_EXECUTOR != null) {
            task.executeOnExecutor(SERIAL_TASK_EXECUTOR);
        } else {
            task.execute();
        }
    }


    /**
     * shutdown method
     * ensure the two ref to be null
     */
    public static void shutdownDataTask() {
        if (dataInstance != null) {
            dataInstance.shutdown();
        }
        dataInstance = null;
        if (DATA_TASK_EXECUTOR != null) {
            DATA_TASK_EXECUTOR.shutdown();
        }
        DATA_TASK_EXECUTOR = null;
    }

    public static void shutdownImgTask() {
        if (downloadImgInstance != null) {
            downloadImgInstance.shutdown();
        }
        downloadImgInstance = null;
        if (DOWNLOAD_IMG_TASK_EXECUTOR != null) {
            DOWNLOAD_IMG_TASK_EXECUTOR = null;
        }
        if (localImgInstance != null) {
            localImgInstance.shutdown();
        }
        localImgInstance = null;
        if (LOCAL_IMG_TASK_EXECUTOR != null) {
            LOCAL_IMG_TASK_EXECUTOR = null;
        }
    }

    public static void shutdownOtherTask() {
        if (otherInstance != null) {
            otherInstance.shutdown();
        }
        otherInstance = null;
        if (OTHER_TASK_EXECUTOR != null) {
            OTHER_TASK_EXECUTOR = null;
        }
    }

    public static void shutdownSoftwareTask() {
        if (downloadSoftwarenstance != null) {
            downloadSoftwarenstance.shutdown();
        }
        downloadSoftwarenstance = null;
        if (DOWNLOAD_SOFTWARE_TASK_EXECUTOR != null) {
            DOWNLOAD_SOFTWARE_TASK_EXECUTOR = null;
        }
    }

    public static void shutdownLongTimeTask() {
        if (longlifeInstance != null) {
            longlifeInstance.shutdown();
        }
        longlifeInstance = null;
        if (LONGTIME_LIFE_TASK_EXECUTOR != null) {
            LONGTIME_LIFE_TASK_EXECUTOR.shutdown();
        }
        LONGTIME_LIFE_TASK_EXECUTOR = null;
    }

    public static void shutdowmSerialTask() {
        if (SERIAL_TASK_EXECUTOR != null) {
            SERIAL_TASK_EXECUTOR.shutdown();
        }
        SERIAL_TASK_EXECUTOR = null;
    }


    /********************************** Debug Use *******************************************/

    /**
     * for Debug
     *
     * @return instance of each Subpool(PoolExecutors)
     */
//    public static GrandCentralPool getInstance() {
//        GrandCentralPool mInstance = new GrandCentralPool();
//        return mInstance;
//    }

//    public static PoolExecutors getDownloadImgInstance() {
//        return downloadImgInstance;
//    }
//
//    public static PoolExecutors getDataInstance() {
//        return dataInstance;
//    }
//
//    public static PoolExecutors getDownloadSoftwarenstance() {
//        return downloadSoftwarenstance;
//    }
//
//    public static PoolExecutors getLocalImgInstance() {
//        return localImgInstance;
//    }
//
//    public static PoolExecutors getOtherInstance() {
//        return otherInstance;
//    }
//
//    public static PoolExecutors getLonglifeInstance() {
//        return longlifeInstance;
//    }

    /**
     * set the DEBUG solider
     */
//    public static void setDebug(boolean setDEBUG) {
//        DEBUG = setDEBUG;
//    }

    /**
     * get the executeMode
     * return a string "Debug" or "Release"
     */
//    public String getExecuteMode() {
//        if (DEBUG) {
//            return "DEBUG";
//        } else {
//            return "Release";
//        }
//    }
}


